﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;

namespace CustomControls
{
    public class ToggleButton : Button
    {
        #region 私有字段
        private bool isOn = false;
        private int sliderX;
        private Color onBackColor = Color.FromArgb(76, 175, 80); // 开启时背景色
        private Color offBackColor = Color.FromArgb(224, 224, 224); // 关闭时背景色
        private Color sliderColor = Color.White; // 滑块颜色
        private System.Windows.Forms.Timer animationTimer;
        private bool isAnimating = false;
        private int animationTarget;
        #endregion

        #region 构造函数
        public ToggleButton()
        {
            // 设置按钮基本属性
            FlatStyle = FlatStyle.Flat;
            FlatAppearance.BorderSize = 0;
            Size = new Size(60, 30);
            DoubleBuffered = true;
            sliderX = 2; // 初始位置

            // 初始化动画定时器
            animationTimer = new System.Windows.Forms.Timer { Interval = 10 };
            animationTimer.Tick += AnimationTimer_Tick;
        }
        #endregion

        #region 公共属性
        /// <summary>
        /// 获取或设置开关状态
        /// </summary>
        [System.ComponentModel.Category("Appearance")]
        [System.ComponentModel.Description("开关状态")]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsOn
        {
            get => isOn;
            set
            {
                if (isOn != value)
                {
                    isOn = value;
                    StartAnimation();
                    Invalidate();
                    OnCheckedChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// 获取或设置开启时的背景色
        /// </summary>
        [System.ComponentModel.Category("Appearance")]
        [System.ComponentModel.Description("开启时的背景色")]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Color OnBackColor
        {
            get => onBackColor;
            set
            {
                onBackColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 获取或设置关闭时的背景色
        /// </summary>
        [System.ComponentModel.Category("Appearance")]
        [System.ComponentModel.Description("关闭时的背景色")]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Color OffBackColor
        {
            get => offBackColor;
            set
            {
                offBackColor = value;
                Invalidate();
            }
        }

        /// <summary>
        /// 获取或设置滑块颜色
        /// </summary>
        [System.ComponentModel.Category("Appearance")]
        [System.ComponentModel.Description("滑块颜色")]
        //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Color SliderColor
        {
            get => sliderColor;
            set
            {
                sliderColor = value;
                Invalidate();
            }
        }
        #endregion

        #region 事件
        /// <summary>
        /// 开关状态改变事件
        /// </summary>
        public event EventHandler CheckedChanged;

        /// <summary>
        /// 触发CheckedChanged事件
        /// </summary>
        protected virtual void OnCheckedChanged(EventArgs e)
        {
            CheckedChanged?.Invoke(this, e);
        }
        #endregion

        #region 私有方法
        // 动画定时器事件
        private void AnimationTimer_Tick(object sender, EventArgs e)
        {
            if (isAnimating)
            {
                if (isOn && sliderX < animationTarget)
                {
                    sliderX += 3;
                    if (sliderX >= animationTarget)
                    {
                        sliderX = animationTarget;
                        isAnimating = false;
                        animationTimer.Stop();
                    }
                    Invalidate();
                }
                else if (!isOn && sliderX > animationTarget)
                {
                    sliderX -= 3;
                    if (sliderX <= animationTarget)
                    {
                        sliderX = animationTarget;
                        isAnimating = false;
                        animationTimer.Stop();
                    }
                    Invalidate();
                }
            }
        }

        // 启动滑块动画
        private void StartAnimation()
        {
            if (isAnimating) return;

            animationTarget = isOn ? Height - 4 : 2;
            isAnimating = true;
            animationTimer.Start();
        }

        // 绘制开关按钮
        protected override void OnPaint(PaintEventArgs pevent)
        {
            base.OnPaint(pevent);

            pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            // 计算圆角矩形区域
            RectangleF rect = new RectangleF(0, 0, Width - 1, Height - 1);
            float radius = Height / 2f;

            // 创建圆角路径
            GraphicsPath path = new GraphicsPath();
            path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
            path.AddArc(rect.X + rect.Width - radius, rect.Y, radius, radius, 270, 90);
            path.AddArc(rect.X + rect.Width - radius, rect.Y + rect.Height - radius, radius, radius, 0, 90);
            path.AddArc(rect.X, rect.Y + rect.Height - radius, radius, radius, 90, 90);
            path.CloseFigure();

            // 填充背景色
            using (Brush backBrush = new SolidBrush(isOn ? onBackColor : offBackColor))
            {
                pevent.Graphics.FillPath(backBrush, path);
            }

            // 绘制滑块
            int sliderSize = Height - 4;
            Rectangle sliderRect = new Rectangle(sliderX, 2, sliderSize, sliderSize);
            using (Brush sliderBrush = new SolidBrush(sliderColor))
            {
                pevent.Graphics.FillEllipse(sliderBrush, sliderRect);
            }

            // 添加阴影效果
            using (Pen shadowPen = new Pen(Color.FromArgb(50, 0, 0, 0)))
            {
                pevent.Graphics.DrawEllipse(shadowPen, sliderRect);
            }
        }

        // 处理鼠标点击事件
        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            IsOn = !IsOn;
        }
        #endregion

        #region 清理资源
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                animationTimer?.Stop();
                animationTimer?.Dispose();
            }
            base.Dispose(disposing);
        }
        #endregion
    }
}